#ifndef tutorialSelection_h
#define tutorialSelection_h

#include "SelectionBase.hxx"
#include "Parameters.hxx"

/* In this file there is an example of selection with a single branch. This is identical to the numuCCSelection (under psycheSelections) 
   used by the numuCCAnalysis in highland2.
   Two define a selection you need in this file:
   - If a specific box is needed (the AnaBoxB is not sufficient) define it first such that it known when the Selection is defined
   - Declare the selection inheriting from SelectionBase or another existing selection
   - Declare all steps needed by the selection
*/


//---- Define the class for the new selection, which should inherit from SelectionBase or from another existing selection -------
class tutorialSelection: public SelectionBase{
 public:
  tutorialSelection(bool forceBreak=true);
  virtual ~tutorialSelection(){}

  //---- Implement four mandatory methods -----

  // In this method all steps are added to the selection
  void DefineSteps();

  // Create a proper instance of the box (AnaBoxB) to store all relevent information to be passed from one step to the next
  AnaBoxB* MakeBox() {return new AnaBoxB();}

  // Fill the event summary information, which is needed by the fitters (BANFF, Mach3)
  bool FillEventSummary(const AnaBoxB& box, AnaEventB& event, Int_t allCutsPassed[]);

  // Return the appropriate sample type
  nd280Samples::SampleEnum GetSampleEnum(){return nd280Samples::kFGD1NuMuCC;}
};

//---- Define all steps -------
class FillSummaryAction_tutorial: public StepBase{
public:
  using StepBase::Apply;
  bool Apply(const AnaEventB& event, AnaBoxB& box) const;  
  StepBase* MakeClone(){return new FillSummaryAction_tutorial();}
};

class TrackQualityFiducialCut: public StepBase{
 public:
  using StepBase::Apply;
  bool Apply(const AnaEventB& event, AnaBoxB& box) const;
  StepBase* MakeClone(){return new TrackQualityFiducialCut();}
};

class TotalMultiplicityCut: public StepBase{
 public:
  using StepBase::Apply;
  bool Apply(const AnaEventB& event, AnaBoxB& box) const;
  StepBase* MakeClone(){return new TotalMultiplicityCut();}
};

class MuonPIDCut: public StepBase{
 public:
  MuonPIDCut(){
    _prod5Cut = false;
  }
  using StepBase::Apply;
  bool Apply(const AnaEventB& event, AnaBoxB& box) const;
  StepBase* MakeClone(){return new MuonPIDCut();}
 private:
  bool _prod5Cut;
};

class ExternalVetoCut: public StepBase{
 public:
  using StepBase::Apply;
  bool Apply(const AnaEventB& event, AnaBoxB& box) const;
  StepBase* MakeClone(){return new ExternalVetoCut();}
};

class DeltaZCut: public StepBase{
 public:
  using StepBase::Apply;
  bool Apply(const AnaEventB& event, AnaBoxB& box) const;
  StepBase* MakeClone(){return new DeltaZCut();}
};

class ExternalFGD1lastlayersCut: public StepBase{
 public:
  using StepBase::Apply;
  bool Apply(const AnaEventB& event, AnaBoxB& box) const;
  StepBase* MakeClone(){return new ExternalFGD1lastlayersCut();}
};

/// Leading tracks with good quality in FGD1
class FindLeadingTracksAction: public StepBase{
 public:
  using StepBase::Apply;
  bool Apply(const AnaEventB& event, AnaBoxB& box) const;
  StepBase* MakeClone(){return new FindLeadingTracksAction();}
};

  /// Find the Vertex. For the moment it's just the Star position of the HM track
class FindVertexAction: public StepBase{
 public:
  using StepBase::Apply;
  bool Apply(const AnaEventB& event, AnaBoxB& box) const;
  StepBase* MakeClone(){return new FindVertexAction();}
};


class FindVetoTrackAction: public StepBase{
 public:
  using StepBase::Apply;
  bool Apply(const AnaEventB& event, AnaBoxB& box) const;
  StepBase* MakeClone(){return new FindVetoTrackAction();}
};

class FindOOFVTrackAction: public StepBase{
 public:
  using StepBase::Apply;
  bool Apply(const AnaEventB& event, AnaBoxB& box) const;
  StepBase* MakeClone(){return new FindOOFVTrackAction();}
};


#endif
